package codeGenerator.visitor;

import java.util.Iterator;

import model.AttributeElement;
import model.ClasseElement;
import model.CompositeElement;
import codeGenerator.JavaFileWriter;

public class GetterSetterPrintingVisitor implements IMetaModelVisitor {

	protected JavaFileWriter mWriter;

	@Override
	public void visitClasseElement(ClasseElement aClasseElement) {

		this.mWriter.printNewLine();

		// Ajout GetSet attributs composite
		Iterator<CompositeElement> compositeIt = aClasseElement.getComposites()
				.iterator();
		while (compositeIt.hasNext()) {
			compositeIt.next().accept(this);
		}

		// Ajout GetSet attributs
		Iterator<AttributeElement> attributeIt = aClasseElement.getAttributes()
				.iterator();
		while (attributeIt.hasNext()) {
			attributeIt.next().accept(this);
		}
	}

	@Override
	public void visitAttributeElement(AttributeElement anAttributeElement) {
		// Ecriture du GETTER
		this.mWriter.tab(1);
		this.mWriter.print(anAttributeElement.getVisibility() + " ");
		this.mWriter.print(anAttributeElement.getType() + " ");

		// Ecriture du nom du getter
		this.mWriter.println("get"
				+ this.getStringWithFirstAsUpperCase(anAttributeElement
						.getName()) + "(){");

		this.mWriter.tab(2);
		this.mWriter.println("return this." + anAttributeElement.getName()
				+ ";");
		this.mWriter.tab(1);
		this.mWriter.println("}");

		// Ecriture du SETTER
		this.mWriter.printNewLine();
		this.mWriter.tab(1);
		this.mWriter.print(anAttributeElement.getVisibility() + " ");

		// Ecriture du type du retour
		this.mWriter.print("void ");

		// Ecriture du nom du setter
		this.mWriter.print("set"
				+ this.getStringWithFirstAsUpperCase(anAttributeElement
						.getName()) + "(");
		this.mWriter.print(anAttributeElement.getType() + " ");
		this.mWriter.println("a" + anAttributeElement.getType() + ") {");

		this.mWriter.tab(2);
		this.mWriter.print("this." + anAttributeElement.getName() + " = ");
		this.mWriter.println("a" + anAttributeElement.getType() + ";");

		this.mWriter.tab(1);
		this.mWriter.println("}");
	}

	@Override
	public void visitCompositeElement(CompositeElement aCompositeElement) {
		// Ecriture du GETTER
		this.mWriter.tab(1);
		this.mWriter.print(aCompositeElement.getVisibility() + " ");

		// Ecriture du type de l'attribut composite
		// Si c'est un attribut non multiple
		if (!aCompositeElement.isMultiple()) {
			this.mWriter.print(aCompositeElement.getCompleteType() + " ");
		}
		// sinon
		else {
			this.mWriter.print("List<" + aCompositeElement.getCompleteType()
					+ "> ");
		}

		// Ecriture du nom du getter
		this.mWriter.println("get"
				+ this.getStringWithFirstAsUpperCase(aCompositeElement
						.getName()) + "() {");

		this.mWriter.tab(2);
		this.mWriter
				.println("return this." + aCompositeElement.getName() + ";");
		this.mWriter.tab(1);
		this.mWriter.println("}");

		// Ecriture du SETTER
		this.mWriter.printNewLine();
		this.mWriter.tab(1);
		this.mWriter.print(aCompositeElement.getVisibility() + " ");

		// Ecriture du type du retour
		this.mWriter.print("void ");

		// Ecriture du nom du setter
		this.mWriter.print("set"
				+ this.getStringWithFirstAsUpperCase(aCompositeElement
						.getName()) + "(");

		// Si c'est un attribut non multiple
		if (!aCompositeElement.isMultiple()) {
			this.mWriter.print(aCompositeElement.getCompleteType() + " ");
		}
		// sinon
		else {
			this.mWriter.print("List<" + aCompositeElement.getCompleteType()
					+ "> ");
		}

		this.mWriter.println("a" + aCompositeElement.getType() + "List) {");

		this.mWriter.tab(2);
		this.mWriter.print("this." + aCompositeElement.getName() + " = ");
		this.mWriter.println("a" + aCompositeElement.getType() + "List;");

		this.mWriter.tab(1);
		this.mWriter.println("}");
	}

	public void setWriter(JavaFileWriter mWriter) {
		this.mWriter = mWriter;
	}

	protected String getStringWithFirstAsUpperCase(String aString) {
		String result = "";
		if (!aString.isEmpty()) {
			result += aString.substring(0, 1).toUpperCase();
			result += aString.substring(1, aString.length());
		}

		return result;
	}
}
